package com.turing.auth_server.jwt;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.support.spring.PropertyPreFilters;
import com.nimbusds.jose.JOSEException;
import com.turing.auth_server.domain.AuthUser;
import com.turing.auth_server.utils.JWTUtiles;
import enums.AuthEnum;
import org.springframework.http.MediaType;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.InternalAuthenticationServiceException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import result.WrapMapper;
import result.Wrapper;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.concurrent.TimeUnit;

/**
 * @path：com.blog.jwt.JWTAuthenticationFilter.java
 * @className：JWTAuthenticationFilter.java
 * @description：权限变动重新授权
 * @author：tanyp
 * @dateTime：2020/11/19 13:15 
 * @editNote：
 */
public class JWTAuthenticationFilter extends UsernamePasswordAuthenticationFilter {

    private AuthenticationManager authenticationManager;

    public JWTAuthenticationFilter(AuthenticationManager authenticationManager) {
        this.authenticationManager = authenticationManager;
    }

    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        return authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(username, password));
    }

    @Override
    protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) throws IOException, ServletException {
        AuthUser user = (AuthUser) authResult.getPrincipal();
        // 生成token
        //要忽略的属性
        String[] excludeProperties = {"authorities"};
        PropertyPreFilters filters = new PropertyPreFilters();
        PropertyPreFilters.MySimplePropertyPreFilter excludeFilter = filters.addFilter();
        excludeFilter.addExcludes(excludeProperties);
        String payload = JSONObject.toJSONString(user, excludeFilter);
        String jwtToken = null;
        try {
            jwtToken = JWTUtiles.createToken(payload);
        } catch (JOSEException e) {
            e.printStackTrace();
        }
        response.setContentType(MediaType.APPLICATION_JSON_VALUE);
        response.setCharacterEncoding("UTF-8");
        response.getWriter().write(JSONObject.toJSONString(WrapMapper.success().result(jwtToken)));
        //解决jwt造成的跨域失效
        /*String requestHeader = request.getHeader("Access-Control-Request-Headers");
        if(requestHeader !=null) {
            response.addHeader("Access-Control-Allow-Headers", requestHeader );
        }
        response.addHeader("Access-Control-Allow-Origin", "*");*/

    }

    @Override
    protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, AuthenticationException failed) throws IOException, ServletException {
        Wrapper result = null;
        int status = AuthEnum.AUTH_NO_TOKEN.getKey();
        if (failed instanceof InternalAuthenticationServiceException) {
            result = WrapMapper.error(AuthEnum.AUTH_NO_ACCOUNT.getKey(), failed.getMessage());
        } else if (failed instanceof BadCredentialsException) {
            result = WrapMapper.error(AuthEnum.AUTH_ERR_PASS.getKey(), AuthEnum.AUTH_ERR_PASS.getValue());
        }
        response.setContentType(MediaType.APPLICATION_JSON_VALUE);
        response.setCharacterEncoding("UTF-8");
        response.setStatus(status);
        response.getWriter().write(JSONObject.toJSONString(result));
        //解决jwt造成的跨域失效
        /*String requestHeader = request.getHeader("Access-Control-Request-Headers");
        if(requestHeader !=null) {
            response.addHeader("Access-Control-Allow-Headers", requestHeader );
        }
        response.addHeader("Access-Control-Allow-Origin", "*");*/
    }

}
